package coreModelTests;

import static org.junit.Assert.*;

import hitExceptions.InvalidOperationException;

import java.awt.Stroke;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import coreModel.*;

public class HITTest {
	static int SIZE=10;
	static List<ProductContainer> storageUnits;

	@BeforeClass
	public static void setUpBeforeClass() 
	{
		try{
			storageUnits= new ArrayList<ProductContainer>();

			for(int x=0;x<SIZE;x++)
			{
				ProductContainer tmp= new StorageUnit("tmp SU");
				try
				{
					tmp.setName("Storage Unit "+x);
				} 
				catch (InvalidOperationException e)
				{
					// TODO Auto-generated catch block
					fail();
				}
				storageUnits.add(tmp);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
			fail();
		}
	}

	@Before
	public void setUp() throws Exception
	{
	}

	@Test
	public void testCanAddStorageUnit()
	{
		//testing can add for true params
		for(ProductContainer x:storageUnits)
		{
			assertTrue(HIT.getInstance().canAddStorageUnit((StorageUnit) x));

		}


	}

	@Test
	public void testAddStorageUnit() throws InvalidOperationException
	{
		//System.out.print(HIT.getInstance().getAllStorageUnits());
		assertTrue(HIT.getInstance().getAllStorageUnits().isEmpty());
		Collection<StorageUnit> c = new ArrayList<StorageUnit>();
		for(ProductContainer x:storageUnits)
		{

			c.add((StorageUnit)x);
			HIT.getInstance().addStorageUnit((StorageUnit)x);
			assertEquals(HIT.getInstance().getAllStorageUnits(),c);

		}
		//testing can add for false params
		for(ProductContainer x:storageUnits)
		{
			assertFalse(HIT.getInstance().canAddStorageUnit((StorageUnit) x));
		}
	}

	@Test
	public void testRemoveStorageUnit()
	{
		Collection<StorageUnit> c = new ArrayList<StorageUnit>();
		for(ProductContainer p: storageUnits)
		{
			c.add((StorageUnit)p);
		}

		for(ProductContainer p: storageUnits)
		{

			assertTrue(HIT.getInstance().canRemoveStorageUnit((StorageUnit)p));
			HIT.getInstance().removeStorageUnit((StorageUnit)p);
			c.remove(p);
			assertEquals(HIT.getInstance().getAllStorageUnits(),c);
		}
	}

	@Test
	public void testCanRemoveStorageUnit() throws InvalidOperationException
	{
		try
		{
			Product tmpProduct = new Product("test Prod",new Barcode());
			for(ProductContainer p: storageUnits)
			{
				assertTrue(HIT.getInstance().canRemoveStorageUnit((StorageUnit)p));
				HIT.getInstance().addStorageUnit((StorageUnit)p);
				p.addItem(new Item(new Barcode(),tmpProduct,p));
				assertFalse(HIT.getInstance().canRemoveStorageUnit((StorageUnit)p));
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}

	}

	@Test
	public void testGetStorageUnit() throws InvalidOperationException
	{
		try
		{
			ProductContainer tmpSU= new StorageUnit("tmp");
			boolean failure= false;
			try
			{
				tmpSU.setName("test");
			} 
			catch (InvalidOperationException e)
			{
				failure=true;
			}
			if(failure)
				fail("I should be able to add a storage unit with that name");


			for(ProductContainer p: storageUnits)
			{
				//added because the can remove stroageunit is not implmented so i need to add the ones that didn't get added in
				if(HIT.getInstance().canAddStorageUnit((StorageUnit)p))
					HIT.getInstance().addStorageUnit((StorageUnit)p);
				assertEquals(HIT.getInstance().getStorageUnit(p.getName()),p);
			}

			assertNull(HIT.getInstance().getStorageUnit(tmpSU.getName()));
		}
		catch(Exception e)
		{
			e.printStackTrace();
			fail();
		}
	}



}
